package org.modelcc.io.java.visitor;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;

import org.modelcc.Separator;
import org.modelcc.io.java.JavaModelReader;
import org.modelcc.io.java.JavaLanguageVisitor;
import org.modelcc.io.java.JavaLanguageMetadata;
import org.modelcc.io.java.JavaLanguageClass;
import org.modelcc.language.metamodel.LanguageMember;
import org.modelcc.lexer.recognizer.PatternRecognizer;
import org.modelcc.lexer.recognizer.regexp.RegExpPatternRecognizer;

/**
 * Java model reader: Class visitor for @Prefix
 * 
 * @author Fernando Berzal (berzal@acm.org)
 */
public class SeparatorVisitor extends JavaLanguageVisitor 
{	
	private JavaLanguageMetadata metadata;
	
	public SeparatorVisitor(JavaModelReader reader, JavaLanguageMetadata metadata)
	{
		super(reader);
		this.metadata = metadata;
	}
	
	@Override
	public void startVisit(Class type, JavaLanguageClass element) 
	{
    	List<PatternRecognizer> separator = null;
    	
    	if (type.isAnnotationPresent(Separator.class)) {
    		Separator an;
    		an = (Separator) type.getAnnotation(Separator.class);
    		PatternRecognizer pr;
    		int k;
    		separator = new ArrayList<PatternRecognizer>();
    		boolean err = false;
    		for (k = 0;k < an.value().length;k++) {
    			if (an.value()[k] == null) {
    				log(Level.SEVERE, "In class \"{0}\": The @Separator value cannot contain null.", new Object[]{type.getCanonicalName()});
    				err = true;
    			}
    			else if (an.value()[k].equals("")) {
    			}
    			else {
    				if (metadata.pas.containsKey(an.value()[k]))
    					pr = metadata.pas.get(an.value()[k]);
    				else {
    					pr = new RegExpPatternRecognizer(an.value()[k]);
    					metadata.pas.put(an.value()[k],pr);
    				}
    				separator.add(pr);
    			}
    		}
    		if (err)
    			separator = null;
    		else
    			metadata.delimiters.addAll(separator);
    	}

    	element.setSeparator(separator);		
 	}

	// Model element member

	public void visit (Field field, LanguageMember member)
	{

    	List<PatternRecognizer> separator = null;

    	if (field.isAnnotationPresent(Separator.class)) {
    		separator = new ArrayList<PatternRecognizer>();
    		Separator an;
    		an = field.getAnnotation(Separator.class);
    		PatternRecognizer pr;
    		int k;
    		for (k = 0;k < an.value().length;k++) {
    			if (an.value()[k] == null) {
    				log(Level.SEVERE, "In field \"{0}\" of class \"{1}\": The @Separator value cannot contain null.", 
    						new Object[]{field.getName(), field.getDeclaringClass().getCanonicalName()});
    			} else if (an.value()[k].equals("")) {
    			} else {
    				if (metadata.pas.containsKey(an.value()[k]))
    					pr = metadata.pas.get(an.value()[k]);
    				else {
    					pr = new RegExpPatternRecognizer(an.value()[k]);
    					metadata.pas.put(an.value()[k],pr);
    				}
    				separator.add(pr);
    				metadata.delimiters.add(pr);
    				//log(Level.INFO,"  Field separator: RegExp \""+allList(an.value())+".");
    			}
    		}
        	member.setSeparator(separator);
    	}		
	}	
}
